﻿#pragma once
#include<thread>
#include<vector>
#include<map>
#include<queue>
#include<atomic>
#include<functional>
#include<mutex>
#include<condition_variable>
#include<chrono>
#include<future>
#include<memory>
using namespace std;

/*
构成：
	1.管理者线程----1个
		控制线程的数量
	2.若干工作线程---n个
		从任务队列中去取任务并处理
	3.任务队列
	4.线程池开关
		开启或关闭线程池
*/

class Thread_pool
{
public:
	Thread_pool(int min = 2 , int max = thread::hardware_concurrency());
	~Thread_pool();

	//添加任务(生产者生产)
	void add_task(function<void(void)>task);
	
	template<typename F,typename... Args>
	auto add_task(F&& f, Args&&... args) -> future<typename result_of<F(Args...)>::type>
	{
		using return_type = typename result_of<F(Args...)>::type;
		auto mytask = make_shared< packaged_task<return_type()>>(
			bind(forward<F>(f), forward<Args>(args)...)
		);
		future<return_type>res = mytask->get_future();

		{
			unique_lock<mutex>lck(m_queue_mutex);
				m_tasks.emplace([mytask]() {
				(*mytask)();
					});
		}

		m_condition.notify_one();

		return res;
	};

private:
	//管理线程
	void manager(void);
	//任务函数(消费者消费)
	void worker(void);
private:
	//管理者线程
	thread* m_manager;
	//工作线程(消费者线程)
	map<thread::id ,thread>m_workers;
	//存储已经退出了任务的线程id
	vector<thread::id>m_ids;
	//最小线程数
	atomic<int> m_minthread;
	//最大线程数
	atomic<int> m_maxthread;
	//当前线程数量
	atomic<int> m_curthread;
	//空闲线程数量
	atomic<int> m_idlethread;
	//退出的线程数量
	atomic<int> m_exithread;
	//线程池开关
	atomic<bool> m_stop;
	//任务队列(生产者线程)
	queue<function<void(void)>>m_tasks;
	//阻塞任务队列的互斥锁
	mutex m_queue_mutex;
	//锁m_ids
	mutex m_ids_mutex;
	//阻塞消费者线程
	condition_variable m_condition;
};